<?php
/** 
 * EGP Framework
 *
 * LICENSE
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */

!defined('EGP_LIB_DIR') && die('Access Deny!');

/**
 * 支付方式工厂类
 *
 * @package    classes
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */
abstract class EGP_Payment
{

    const STAT_INITED   = 0; //初始状态，未确认
    const STAT_WAIT_PAY = 1; //已确认，等待付款
    const STAT_PAID     = 2; //买家已付款，等待发货
    const STAT_SHIPPED  = 3; //卖家已发货，等待收货
    const STAT_RECEIVED = 4; //已收货
    const STAT_SUCCEED  = 5; //支付成功 (完成)
    const STAT_TIMEOUT  = 6; //支付超时
    const STAT_FAILED   = 7; //支付失败 (完成)

    /**
     * 支付数据存储器
     *
     * @var EGP_Payment_Storage_Interface
     */
    protected static $_storage = null;

    /**
     * 设置支付数据存储器
     *
     * @param  EGP_Payment_Storage_Interface  $storage
     */
    public static function setStorage(EGP_Payment_Storage_Interface $storage)
    {
        self::$_storage = $storage;
    }

    /**
     * 获取支付数据存储器
     *
     * @return EGP_Payment_Storage_Interface
     */
    public static function getStorage()
    {
        if (null === self::$_storage) {
            self::setStorage(new EGP_Payment_Storage_File());
        }

        return self::$_storage;
    }

    /**
     * 创建支付方式
     *
     * @param  string  $adapter
     * @param  mixed   $config
     * @return EGP_Payment_Adapter_Abstract
     * @throws EGP_Exception
     */
    public static function create($adapter, $config = array())
    {
        $payment = self::_getAdapterInstance('Adapter', $adapter, $config);

        if (!$payment) {
            throw new EGP_Exception("不支持的支付方式 '$adapter'");
        }

        return $payment;
    }

    /**
     * 创建支付响应
     *
     * @param  string  $adapter
     * @param  mixed   $params
     * @return EGP_Payment_Respond_Abstract
     * @throws EGP_Exception
     */
    public static function respond($adapter, array $params = array())
    {
        $respond = self::_getAdapterInstance('Respond', $adapter, $params);

        if (!$respond) {
            throw new EGP_Exception("不支持的支付方式 '$adapter'");
        }

        return $respond;
    }

    /**
     * 获取适配器实例
     *
     * @param  string  $prefix
     * @param  string  $adapter
     * @param  mixed   $params
     * @return boolean|object
     */
    protected static function _getAdapterInstance($prefix, $adapter, $params = array())
    {
        $adapter = implode('_', array_map('ucfirst', explode('_', $adapter)));
        $class = "EGP_Payment_{$prefix}_{$adapter}";
        if (!EGP_Core::classExists($class)) {
            return false;
        }

        if ($params instanceof EGP_ArrayObject) {
            $params = $params->toArray();
        }

        if (!is_array($params)) {
            throw new EGP_Exception('配置参数必须是一个有效的数组 (Array)');
        }

        $obj = new $class($params);
        return (is_subclass_of($obj, "EGP_Payment_{$prefix}_Abstract")) ? $obj : false;
    }

}